`include "mycpu.h"
module wb_stage(
    input clk,
    input reset,
    //WB allowin
    output ws_allowin,
    //MEM to WB
    input ms_to_ws_valid,
    input [`MS_TO_WS_WD - 1:0] ms_to_ws_bus,
    //WB to ID
    output [`WS_TO_RF_WD - 1:0] ws_to_rf_bus,
    output out_ws_valid,
    //debug
    output [31:0] debug_wb_rf_pc,
    output [3:0] debug_wb_rf_we,
    output [4:0] debug_wb_rf_wnum,
    output [31:0] debug_wb_rf_wdata
);

reg ws_valid;
wire ws_ready_go;
reg [`MS_TO_WS_WD - 1:0] ms_to_ws_bus_r;
wire [31:0] ws_pc;
wire [31:0] ws_final_result;
wire [4:0] ws_dest;
wire ws_gr_we;
wire ws_rf_we;

assign out_ws_valid = ws_valid;

assign ws_ready_go = 1'b1;

assign ws_allowin = !ws_valid || ws_ready_go;

always @(posedge clk) begin
    if(reset)
        ws_valid <= 1'b0;
    else if(ws_allowin)
        ws_valid <= ms_to_ws_valid;
end

always @(posedge clk) begin
    if(ws_allowin && ms_to_ws_valid) 
        ms_to_ws_bus_r <= ms_to_ws_bus;
end

assign {
    ws_pc[31:0],
    ws_gr_we,
    ws_dest[4:0],
    ws_final_result[31:0] } = ms_to_ws_bus_r[`MS_TO_WS_WD - 1:0];


//WB to RF
assign ws_rf_we = ws_gr_we && ws_valid;

assign ws_to_rf_bus[`WS_TO_RF_WD - 1:0] = {
    ws_gr_we,               //37:37
    ws_dest[4:0],           //36:32
    ws_final_result[31:0]   //31:0
};

assign debug_wb_rf_pc = ws_pc;
assign debug_wb_rf_we = {4{ws_rf_we}};
assign debug_wb_rf_wnum = ws_dest;
assign debug_wb_rf_wdata = ws_final_result;

endmodule
